package com.fantesy.jwtdemo.util;

import com.fantesy.jwtdemo.entity.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author fantsey
 * @date 2020/2/27
 * 官方地址：https://github.com/jwtk/jjwt
 */
public class JWTTokenUtils {

    private static final String SCREAT = "www.fantsey.com123456789www.fantsey.com123456789";
    // 秘钥, 要求秘钥必须超过256bit才够安全
    private static SecretKey secretKey = Keys.hmacShaKeyFor(SCREAT.getBytes());

    // 生成token
    public static String getJWTToken(User user){


        //创建payload的私有声明（根据特定的业务需要添加，如果要拿这个做验证，一般是需要和jwt的接收方提前沟通好验证方式的）
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getUserId());
        claims.put("username", user.getUsername());
        claims.put("password", user.getPassword());



        String token = Jwts.builder()
                // 如果有私有声明，一定要先设置这个自己创建的私有的声明，这个是给builder的claim赋值，一旦写在标准的声明赋值之后，就是覆盖了那些标准的声明的
                .setClaims(claims)
                // 设置JID
                .setId(UUID.randomUUID().toString())
                // 签发时间
                .setIssuedAt(new Date())
                //代表这个JWT的主体，即它的所有人，这个是一个json格式的字符串，可以存放什么userid，roldid之类的，作为什么用户的唯一标志。
                .setSubject(user.getUsername())
                // 根据自己的秘钥，设置签名，并指定签名算法
                .signWith(secretKey, SignatureAlgorithm.HS256)
                .compact();
        return token;
    }

    // 验证token
    public static Claims parseClaims(String token){
        Jws<Claims> claimsJws = Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);
        Claims body = claimsJws.getBody();
        return body;
    }


    public static void main(String[] args) {
        User user = new User();
        user.setUserId("123456");
        user.setUsername("van");
        user.setPassword("123456");
        String token = getJWTToken(user);
        System.out.println(token);

        Claims body = parseClaims(token);
        String username = (String)body.get("username");
        System.out.println(username);
    }
}
